package other.her.system.erp;

import com.alibaba.fastjson.JSONObject;
import com.rkhd.platform.sdk.ScheduleJob;
import com.rkhd.platform.sdk.api.annotations.RequestMethod;
import com.rkhd.platform.sdk.api.annotations.RestApi;
import com.rkhd.platform.sdk.api.annotations.RestMapping;
import com.rkhd.platform.sdk.data.model.ARRECEIVEBILL__c;
import com.rkhd.platform.sdk.data.model.IVSALESIC__c;
import com.rkhd.platform.sdk.exception.AsyncTaskException;
import com.rkhd.platform.sdk.exception.ScriptBusinessException;
import com.rkhd.platform.sdk.log.Logger;
import com.rkhd.platform.sdk.log.LoggerFactory;
import com.rkhd.platform.sdk.param.ScheduleJobParam;
import com.rkhd.platform.sdk.service.FutureTaskService;
import com.rkhd.platform.sdk.service.XoqlService;
import com.rkhd.platform.sdk.task.FutureTask;
import other.her.system.client.ErpUtils;
import other.her.system.utils.HCXObjectService;
import other.her.system.utils.ResultVo;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description: 定时处理同步的数据：1.处理收款下关联的发票 2.处理发票下关联的出库
 * @Author: 黎炎松
 * @Date: 2024/11/29 16:39
 */
@RestApi(baseUrl = "/her/dealEmptyNo")
public class DealEmptyNo extends SyncSuper implements ScheduleJob, FutureTask {

    private static final Logger LOGGER = LoggerFactory.getLogger();

    private static final String LOGGER_MSG = "处理同步关联的数据 ==> ";

    private static final XoqlService xoqlService = XoqlService.instance();

    /**
     * 计划作业触发
     * @param scheduleJobParam
     */
    @Override
    public void execute(ScheduleJobParam scheduleJobParam) {
        LOGGER.info(LOGGER_MSG + "触发计划作业");
        try {
            String messageId = FutureTaskService.instance().addFutureTask(getClass(), "");
            LOGGER.info(LOGGER_MSG + "异步ID:" + messageId);
        } catch (Exception e) {
            LOGGER.error(LOGGER_MSG + " ----- 发生异常：" + e.getMessage());
        }
    }

    /**
     * 异步执行
     * @param type
     * @throws ScriptBusinessException
     */
    @Override
    public void execute(String type) {
        LOGGER.info(LOGGER_MSG + "触发异步同步");
        // 执行同步
        startDeal();
    }

    @RestMapping(value = "/hander", method = RequestMethod.GET)
    public ResultVo hander() throws AsyncTaskException {
        FutureTaskService.instance().addFutureTask(getClass(), "");
        return ResultVo.success("开始处理中~");
    }

    public static void main(String[] args) {
        HCXObjectService.isLocal = true;
        DealEmptyNo dealEmptyNo = new DealEmptyNo();
        dealEmptyNo.startDeal();
    }

    public void startDeal() {
        // 处理不同账套的数据
        for (Map<String, String> account : accountList) {
            startDealEmptyNo(account);
        }
    }

    /**
     * 处理同步的数据  1.处理收款下关联的发票 2.处理发票下关联的出库 （收款关联发票、发票关联出库，只处理 2024年11月30号 15:00 后面的数据）
     */
    public void startDealEmptyNo(Map<String, String> account) {
        try {
            LOGGER.info("开始处理");
            String domain = account.get("domain");

            // 查询没有关联发票的收款单数据
            String sql = "select id,ERPID__c,EntryID__c from ARRECEIVEBILL__c where FBillNoSRC__c is null and createdAt > 1732950000000 limit 200";
            List<JSONObject> receiptList = xoqlService.query(sql).getRecords();
            LOGGER.info(LOGGER_MSG + "receiptList = " + receiptList.size());
            if (receiptList.size() > 0) {
                // 延迟2s
                Thread.sleep(2000);

                // 查询ERP关联的发票数据 收款：ARRECEIVEBILL__c  发票：IVSALESIC__c  出库：salesOutboundOrder__c
                String erpIds = receiptList.stream().map(v -> v.getString("ERPID__c")).distinct().collect(Collectors.joining(","));
                String erpSql = String.format("select FBillID,FIndex,FBillNo_SRC,FID_SRC from t_rp_ARBillOfSH where FBillID in (%s)", erpIds);
                List<JSONObject> erpDataList = ErpUtils.query(erpSql, domain);
                Map<String, String> erpBillMap = erpDataList.stream().collect(Collectors.toMap(e -> e.getString("FBillID") + e.getString("FIndex"), e1 -> e1.getString("FBillNo_SRC"), (e, e1) -> e));
                String billIds = erpDataList.stream().map(v -> v.getString("FID_SRC")).distinct().collect(Collectors.joining(","));
                LOGGER.info(LOGGER_MSG + "billIds = " + billIds);

                // 新增关联的发票数据
                SyncSaleInvoice saleInvoice = new SyncSaleInvoice();
                saleInvoice.syncErpSaleInvoice(account, String.format(" and t0.FInterID in (%s) ", billIds), 1);

                // 获取新增的发票数据
                sql = String.format("select id,name from IVSALESIC__c where ERPID__c in (%s)", billIds);
                Map<String, Long> crmSaleInvoiceMap = xoqlService.query(sql).getRecords().stream().collect(Collectors.toMap(e -> e.getString("name"), e1 -> e1.getLong("id"), (e, e1) -> e));

                // 更新销售收款
                List<ARRECEIVEBILL__c> crmUpList =new ArrayList<>();
                for (JSONObject receipt : receiptList) {
                    ARRECEIVEBILL__c arreceivebill = new ARRECEIVEBILL__c();
                    arreceivebill.setId(receipt.getLong("id"));

                    // 获取对应的发票id
                    String entryId = receipt.getString("EntryID__c");
                    String billNo = erpBillMap.get(entryId);
                    if (!crmSaleInvoiceMap.containsKey(billNo)) {
                        continue;
                    }

                    arreceivebill.setFBillNoSRC__c(crmSaleInvoiceMap.get(billNo));
                    crmUpList.add(arreceivebill);
                }
                LOGGER.info(LOGGER_MSG + "crmUpList = " + crmUpList.size());
                HCXObjectService.updateBatch(crmUpList);
            }

            // 查询没有关联出库的发票数据
            sql = "select id,ERPID__c,EntryID__c from IVSALESIC__c where FRSCBillNo__c is null and createdAt > 1732950000000 limit 200";
            List<JSONObject> invoiceList = xoqlService.query(sql).getRecords();
            LOGGER.info(LOGGER_MSG + "invoiceList = " + invoiceList.size());
            if (invoiceList.size() > 0) {
                // 延迟2s
                Thread.sleep(2000);

                // 查询ERP关联的出库数据 收款：ARRECEIVEBILL__c  发票：IVSALESIC__c  出库：salesOutboundOrder__c
                String erpIds = invoiceList.stream().map(v -> v.getString("ERPID__c")).distinct().collect(Collectors.joining(","));
                String erpSql = String.format("select t0.FInterID,t0.FEntryID,bi.FBillNo,bi.FInterID as FBillID " +
                        " from ICSaleEntry t0 left join ICStockBill bi on t0.FSourceInterId = bi.FInterID where t0.FInterID in (%s)", erpIds);
                List<JSONObject> erpDataList = ErpUtils.query(erpSql, domain);
                Map<String, String> erpBillMap = erpDataList.stream().collect(Collectors.toMap(e -> e.getString("FInterID") + e.getString("FEntryID"), e1 -> e1.getString("FBillNo"), (e, e1) -> e));
                String billIds = erpDataList.stream().map(v -> v.getString("FBillID")).distinct().collect(Collectors.joining(","));
                LOGGER.info(LOGGER_MSG + "billIds = " + billIds);

                // 新增关联的出库数据
                SyncSaleOut syncSaleOut = new SyncSaleOut();
                syncSaleOut.syncErpSaleOut(account, String.format(" and t0.FInterID in (%s)", billIds));

                // 获取新增的出库数据
                sql = String.format("select id,name from salesOutboundOrder__c where ERPID__c in (%s)", billIds);
                Map<String, Long> crmSaleOutMap = xoqlService.query(sql).getRecords().stream().collect(Collectors.toMap(e -> e.getString("name"), e1 -> e1.getLong("id"), (e, e1) -> e));

                // 更新销售发票
                List<IVSALESIC__c> crmUpList =new ArrayList<>();
                for (JSONObject invoice : invoiceList) {
                    IVSALESIC__c ivsalesic = new IVSALESIC__c();
                    ivsalesic.setId(invoice.getLong("id"));

                    // 获取对应的出库id
                    String entryId = invoice.getString("EntryID__c");
                    String billNo = erpBillMap.get(entryId);
                    if (!crmSaleOutMap.containsKey(billNo)) {
                        continue;
                    }

                    ivsalesic.setFRSCBillNo__c(crmSaleOutMap.get(billNo));
                    crmUpList.add(ivsalesic);
                }
                LOGGER.info(LOGGER_MSG + "crmUpList = " + crmUpList.size());
                HCXObjectService.updateBatch(crmUpList);
            }

            LOGGER.info("处理成功");
        } catch (Exception e) {
            e.printStackTrace();
            LOGGER.error("处理异常: " + e.getMessage());
        }



    }

}
